package hero_info

import (
	"go_server/game_server/api/service/build"
	"go_server/game_server/api/service/item"
	"go_server/game_server/constants"
	"go_server/game_server/dataconfig/config_manager"
	"go_server/game_server/protocol/pb"
	"go_server/game_server/util"
	"go_server/zinx/zlog"
	"math"
	"strconv"
	"strings"
)

// ===================================================================================================================
// 数据库表【hero_info】
//
// Cache_hero_info
//
// ===================================================================================================================
type Cache_hero_info struct {
	RoleId    int64
	RoleCells map[int32]*Cache_hero_info_field_cell //[Serid]玩家拥有的细胞
	Heros     map[int32]*Cache_hero_info_field_hero //[Serid]玩家拥有的英雄
}

func (h *Cache_hero_info) GetMaxHeroSerId() int32 {
	maxSerid := int32(0)
	if h.Heros != nil {
		for sid, _ := range h.Heros {
			maxSerid = int32(math.Max(float64(sid), float64(maxSerid)))
		}
	}
	return maxSerid
}

func (h *Cache_hero_info) Contains(heroCfgId int32) bool {
	isContains := false
	if h.Heros != nil {
		for _, v := range h.Heros {
			if v.CfgId == heroCfgId {
				isContains = true
				break
			}
		}
	}
	return isContains
}

func (h *Cache_hero_info) GetHero(herocfgid int32) (*Cache_hero_info_field_hero, bool) {
	hasHero := false
	for _, hero := range h.Heros {
		hasHero = hero.CfgId == herocfgid
		if hasHero {
			return hero, true
		}
	}
	return nil, false
}

func (h *Cache_hero_info) AddHero(cfgid int32) (*Cache_hero_info_field_hero, bool, pb.ErrorCodeManager) {
	if h.Contains(cfgid) {
		return nil, false, pb.ErrorCodeManager_HERO_INFO_NOT_HEROCFGID
	} else if v, ok := h.GetHero(cfgid); ok {
		return v, false, pb.ErrorCodeManager_HERO_EXISTS
	} else {
		cfgHero, _ := config_manager.GetStcTableHero_SheetHeroConfig(cfgid)
		newHero := &Cache_hero_info_field_hero{SerId: h.GetMaxHeroSerId() + 1, LvId: 1, StarId: 1, CfgId: cfgHero.Id}
		newHero.Skills = make(map[int32]*Cache_hero_info_field_skill)
		//技能
		for i := 0; i < len(cfgHero.Skills); i++ {
			ns := &Cache_hero_info_field_skill{
				Serid: newHero.GetMaxSkillSerid() + 1,
				CfgId: cfgHero.Skills[i],
				Lv:    1,
			}
			newHero.Skills[ns.CfgId] = ns
		}
		//细胞

		newHero.CalculateFight()
		h.Heros[newHero.SerId] = newHero

		//defer func() {
		//	event_manager.EventManagerObj.FireEventData(event_impl.NewAddHeroEvent(world_manager.WorldMgrObj.GetPlayerConn(h.RoleId), newHero.SerId))
		//}()
		return newHero, true, pb.ErrorCodeManager_SUCCESS
	}
}

// ------------------------------------分隔线----------------------------------------------------------------
func (h *Cache_hero_info) MaxSerid_RoleCell() int32 {
	maxserid := int32(0)
	if h.RoleCells != nil {
		for _, cell := range h.RoleCells {
			maxserid = int32(math.Max(float64(maxserid), float64(cell.Serid)))
		}
	}
	return maxserid
}

// 细胞是否足够 cells map[int32:细胞服务器id]int32:细胞数量
func (h *Cache_hero_info) CheckEnoughCell(cells map[int32]int32) bool {
	isEnough := false
	if h.RoleCells != nil && cells != nil && len(cells) > 0 {
		isEnough = true
		for sid, cnt := range cells {
			if cv, c1 := h.RoleCells[sid]; c1 {
				isEnough = isEnough && (cv.Count >= cnt)
			}
		}
	}
	return isEnough
}

// 添加细胞 map[int32:细胞Serid]*Cache_hero_info_field_cell
func (h *Cache_hero_info) AddRoleCell(cells map[int32]int32) (map[int32]*Cache_hero_info_field_cell, bool) {
	if cells != nil && len(cells) > 0 {

		//map[int32:服务器id]*Cache_hero_info_field_cell
		rstcells := make(map[int32]*Cache_hero_info_field_cell, 0)
		//cfgid
		usedatas := util.NewSet[int32]()

		if h.RoleCells != nil {
			//对已存在的细胞增加数量
			for _, rc := range h.RoleCells {
				if ct, c1 := cells[rc.CfgId]; c1 {
					if g, g1 := config_manager.GetStcTableHeroCell_SheetCell(rc.CfgId); g1 {
						if g.Level == rc.Lv { //如果是相同等级细胞，则增加数量
							rc.Count += ct
							rstcells[rc.Serid] = rc
							usedatas.Add(rc.CfgId)
						}
					}
				}
			}
		} else {
			h.RoleCells = make(map[int32]*Cache_hero_info_field_cell)
		}

		eles := usedatas.Elements()
		for i := 0; i < len(eles); i++ {
			delete(cells, eles[i]) //去掉已处理过的数据
		}

		maxserid := h.MaxSerid_RoleCell()
		for cfgid, count := range cells {
			if g, g1 := config_manager.GetStcTableHeroCell_SheetCell(cfgid); g1 {
				maxserid++
				tc := &Cache_hero_info_field_cell{
					Serid: maxserid,
					CfgId: cfgid,
					Lv:    g.Level,
					Count: count,
				}
				rstcells[tc.Serid] = tc
				h.RoleCells[tc.Serid] = tc
			}
		}
		return rstcells, true
	}
	return nil, false
}

// 移除细胞 map[int32:细胞Serid]*Cache_hero_info_field_cell
func (h *Cache_hero_info) RemoveRoleCell(cells map[int32]int32) (map[int32]*Cache_hero_info_field_cell, bool) {
	if h.RoleCells != nil && cells != nil && len(cells) > 0 {
		zeroSerids := util.NewSet[int32]()
		rstCells := make(map[int32]*Cache_hero_info_field_cell)

		for sid, cv := range h.RoleCells {
			if cnt, c1 := cells[sid]; c1 {
				cv.Count -= cnt
				if cv.Count <= 0 {
					cv.Count = 0
					zeroSerids.Add(sid)
				}
				rstCells[sid] = cv
			}
		}
		if zeroSerids.Size() > 0 {
			zcs := zeroSerids.Elements()
			for i := 0; i < len(zcs); i++ {
				delete(h.RoleCells, zcs[i])
			}
		}

		return rstCells, true
	} else {
		return nil, false
	}
}

// ===================================================================================================================
// 数据库表【hero_info】 heros字段
//
// Cache_hero_info
//
// ===================================================================================================================
type Cache_hero_info_field_hero struct {
	SerId  int32                                  //英雄服务器Id
	CfgId  int32                                  //英雄配置Id
	LvId   int32                                  //英雄等级
	StarId int32                                  //英雄星级
	Fight  int32                                  //战力
	Exp    int32                                  //经验
	Skills map[int32]*Cache_hero_info_field_skill //key:技能Serid
	Cells  map[int]*Cache_hero_info_field_cell    //Key:细胞位置索引【装备的细胞】
}

// ------------------------------------分隔线----------------------------------------------------------------
func (h *Cache_hero_info_field_hero) set_value_db(val string) {
	splitStr := strings.Split(val, "_")
	if len(splitStr) > 0 {
		for i, sv := range splitStr {
			if v, err := strconv.Atoi(sv); err == nil {
				switch i {
				case 0:
					{
						h.SerId = int32(v)
					}
				case 1:
					{
						h.CfgId = int32(v)
					}
				case 2:
					{
						h.LvId = int32(v)
					}
				case 3:
					{
						h.StarId = int32(v)
					}
				case 4:
					{
						h.Fight = int32(v)
					}
				case 5:
					{
						h.Exp = int32(v)
					}
				}
			}
		}
	}
}

func (h *Cache_hero_info_field_hero) get_value_db() string {
	combinStr := strings.Join([]string{
		strconv.FormatInt(int64(h.SerId), 10),
		strconv.FormatInt(int64(h.CfgId), 10),
		strconv.FormatInt(int64(h.LvId), 10),
		strconv.FormatInt(int64(h.StarId), 10),
		strconv.FormatInt(int64(h.Fight), 10),
		strconv.FormatInt(int64(h.Exp), 10),
	}, "_")
	return combinStr
}

func (h *Cache_hero_info_field_hero) get_next_star() int32 {
	return h.StarId + 1
}

func (h *Cache_hero_info_field_hero) get_next_lv() int32 {
	return h.LvId + 1
}

// ------------------------------------分隔线----------------------------------------------------------------
func (h *Cache_hero_info_field_hero) set_value_db_skills(vals []string) {
	if vals != nil {
		h.Skills = make(map[int32]*Cache_hero_info_field_skill)
		for i := 0; i < len(vals); i++ {
			v := vals[i]
			t := &Cache_hero_info_field_skill{}
			t.set_value_db(v)
			h.Skills[t.CfgId] = t
		}
	}
}

func (h *Cache_hero_info_field_hero) get_value_db_skills() []string {
	vals := make([]string, 0)
	if h.Skills != nil {
		for _, sv := range h.Skills {
			vals = append(vals, sv.get_value_db())
		}
	}
	return vals
}

// ------------------------------------分隔线----------------------------------------------------------------
func (h *Cache_hero_info_field_hero) set_value_db_cells(vals []string) {
	if vals != nil {
		h.Cells = make(map[int]*Cache_hero_info_field_cell, 0)
		for i := 0; i < len(vals); i++ {
			v := vals[i]
			nc := &Cache_hero_info_field_cell{}
			nc.set_value_db(v)
			h.Cells[i] = nc
		}
	}
}

func (h *Cache_hero_info_field_hero) get_value_db_cells() []string {
	vals := make([]string, 0)
	if h.Cells != nil {
		for _, sv := range h.Cells {
			vals = append(vals, sv.get_value_db())
		}
	}
	return vals
}

// ------------------------------------分隔线----------------------------------------------------------------

func (h *Cache_hero_info_field_hero) GetMaxSkillSerid() int32 {
	maxserid := int32(0)
	if h.Skills != nil {
		for sid, _ := range h.Skills {
			maxserid = int32(math.Max(float64(maxserid), float64(sid)))
		}
	}
	return maxserid
}

func (h *Cache_hero_info_field_hero) GetMaxCellSerid() int32 {
	maxserid := int32(0)
	if h.Skills != nil {
		for _, cv := range h.Cells {
			maxserid = int32(math.Max(float64(maxserid), float64(cv.Serid)))
		}
	}
	return maxserid
}

type type_hero_fightPro int //对应：property.xlsx表abbreviation属性

const (
	hero_fightPro_hp         type_hero_fightPro = 1   //英雄生命
	hero_fightPro_att                           = 2   //英雄攻击
	hero_fightPro_def                           = 3   //英雄防御
	hero_fightPro_cri                           = 4   //英雄暴击
	hero_fightPro_cbr                           = 5   //英雄暴伤
	hero_fightPro_cdr                           = 6   //英雄抗暴
	hero_fightPro_hit                           = 7   //英雄命中
	hero_fightPro_eva                           = 8   //英雄闪避
	hero_fightPro_dmg                           = 9   //英雄伤害增加
	hero_fightPro_drd                           = 10  //英雄增加减免
	hero_fightPro_ite                           = 11  //英雄治疗效果提升
	hero_fightPro_rte                           = 12  //英雄治疗效果降低
	hero_fightPro_blood                         = 13  //英雄吸血
	hero_fightPro_shield                        = 14  //英雄护盾
	hero_fightPro_return                        = 15  //英雄反击
	hero_fightPro_p2hp                          = 16  //英雄生命百分比
	hero_fightPro_p2att                         = 17  //英雄攻击百分比
	hero_fightPro_p2def                         = 18  //英雄防御百分比
	hero_fightPro_attspeed                      = 19  //英雄攻击速度
	hero_fightPro_p2_hp                         = 101 //英雄增加士兵生命百分比
	hero_fightPro_p2_att                        = 102 //英雄增加士兵攻击百分比
	hero_fightPro_p2_def                        = 103 //英雄增加士兵防御百分比
	hero_fightPro_cap                           = 104 //士兵出征容量
	hero_fightPro_p2_jhp                        = 105 //集结英雄增加士兵生命百分比
	hero_fightPro_p2_jatt                       = 106 //集结英雄增加士兵攻击百分比
	hero_fightPro_p2_jdef                       = 107 //集结英雄增加士兵防御百分比
	hero_fightPro_p2_php                        = 108 //pve英雄增加士兵生命百分比
	hero_fightPro_p2_patt                       = 109 //pve英雄增加士兵攻击百分比
	hero_fightPro_p2_pdef                       = 110 //pve英雄增加士兵防御百分比
	hero_fightPro_p2_zhp                        = 111 //驻守英雄增加士兵生命百分比
	hero_fightPro_p2_zatt                       = 112 //驻守英雄增加士兵攻击百分比
	hero_fightPro_p2_zdef                       = 113 //驻守英雄增加士兵防御百分比
	hero_fightPro_p2_ghp                        = 114 //攻击英雄增加士兵生命百分比
	hero_fightPro_p2_gatt                       = 115 //攻击英雄增加士兵攻击百分比
	hero_fightPro_p2_gdef                       = 116 //攻击英雄增加士兵防御百分比
	hero_fightPro_p2_corn                       = 117 //粮食采集
	hero_fightPro_p2_stone                      = 118 //石材采集
	hero_fightPro_p2_iron                       = 119 //铁矿采集
	hero_fightPro_p2_pet                        = 120 //石油采集
	hero_fightPro_p2_move                       = 121 //出征速度
	hero_fightPro_p2_pvemove                    = 122 //pve出征速度
	hero_fightPro_p2_pvpmove                    = 123 //pvp出征速度
)

// 计算战力
func (h *Cache_hero_info_field_hero) CalculateFight() {

	pvratio := make(map[type_hero_fightPro]float32) //属性值偏移比例

	pvs := make(map[type_hero_fightPro]int32)   //属性固定值
	pps := make(map[type_hero_fightPro]float32) //属性百分比值

	if hero, h1 := config_manager.GetStcTableHero_SheetHeroConfig(h.CfgId); h1 {
		pvratio[hero_fightPro_cap] += float32(hero.P2Pycap)
		pvratio[hero_fightPro_hp] += float32(hero.P2Pyhp)
		pvratio[hero_fightPro_att] += float32(hero.P2Pyatt)
		pvratio[hero_fightPro_def] += float32(hero.P2Pydef)

		pvratio[hero_fightPro_p2_hp] += float32(hero.P2Hp)
		pvratio[hero_fightPro_p2_att] += float32(hero.P2Att)
		pvratio[hero_fightPro_p2_def] += float32(hero.P2Def)
		pvratio[hero_fightPro_p2_jhp] += float32(hero.P2Jhp)
		pvratio[hero_fightPro_p2_jatt] += float32(hero.P2Jatt)
		pvratio[hero_fightPro_p2_jdef] += float32(hero.P2Jdef)
		pvratio[hero_fightPro_p2_php] += float32(hero.P2Php)
		pvratio[hero_fightPro_p2_patt] += float32(hero.P2Patt)
		pvratio[hero_fightPro_p2_pdef] += float32(hero.P2Pdef)
		pvratio[hero_fightPro_p2_zhp] += float32(hero.P2Zhp)
		pvratio[hero_fightPro_p2_zatt] += float32(hero.P2Zatt)
		pvratio[hero_fightPro_p2_zdef] += float32(hero.P2Zdef)
		pvratio[hero_fightPro_p2_ghp] += float32(hero.P2Ghp)
		pvratio[hero_fightPro_p2_gatt] += float32(hero.P2Gatt)
		pvratio[hero_fightPro_p2_gdef] += float32(hero.P2Gdef)
		pvratio[hero_fightPro_p2_corn] += float32(hero.P2Corn)
		pvratio[hero_fightPro_p2_stone] += float32(hero.P2Stone)
		pvratio[hero_fightPro_p2_iron] += float32(hero.P2Iron)
		pvratio[hero_fightPro_p2_pet] += float32(hero.P2Pet)
		pvratio[hero_fightPro_p2_pvemove] += float32(hero.P2Pvemove)
		pvratio[hero_fightPro_p2_pvpmove] += float32(hero.P2Pvpmove)
	}

	if lv, l1 := config_manager.GetStcTableHero_SheetLevelConfig(h.LvId); l1 {
		pvs[hero_fightPro_cap] += lv.Cap
		pvs[hero_fightPro_hp] += lv.Hp
		pvs[hero_fightPro_att] += lv.Att
		pvs[hero_fightPro_def] += lv.Def
	}

	if star, s1 := config_manager.GetStcTableHero_SheetStarConfig(h.StarId); s1 {
		pvs[hero_fightPro_hp] += star.Hp
		pvs[hero_fightPro_att] += star.Att
		pvs[hero_fightPro_def] += star.Def

		pps[hero_fightPro_p2_hp] += star.P2Hp
		pps[hero_fightPro_p2_att] += float32(star.P2Att)
		pps[hero_fightPro_p2_def] += float32(star.P2Def)
		pps[hero_fightPro_p2_jhp] += star.P2Jhp
		pps[hero_fightPro_p2_jatt] += star.P2Jatt
		pps[hero_fightPro_p2_jdef] += star.P2Jdef
		pps[hero_fightPro_p2_php] += star.P2Php
		pps[hero_fightPro_p2_patt] += star.P2Patt
		pps[hero_fightPro_p2_pdef] += star.P2Pdef
		pps[hero_fightPro_p2_zhp] += star.P2Zhp
		pps[hero_fightPro_p2_zatt] += star.P2Zatt
		pps[hero_fightPro_p2_zdef] += star.P2Zdef
		pps[hero_fightPro_p2_ghp] += star.P2Ghp
		pps[hero_fightPro_p2_gatt] += star.P2Gatt
		pps[hero_fightPro_p2_gdef] += star.P2Gdef
		pps[hero_fightPro_p2_corn] += star.P2Corn
		pps[hero_fightPro_p2_stone] += star.P2Stone
		pps[hero_fightPro_p2_iron] += star.P2Iron
		pps[hero_fightPro_p2_pet] += star.P2Pet
		pps[hero_fightPro_p2_pvemove] += star.P2Pvemove
		pps[hero_fightPro_p2_pvpmove] += star.P2Pvpmove
	}

	tmpvFight := float32(0)
	tmppFight := float32(0)

	for id, val := range pvs {
		if cfg, ok := config_manager.GetConfigStcTableProperty_SheetProperty(int32(id)); ok {
			if rv, r1 := pvratio[id]; r1 {
				tfv := float32(cfg.Power*val) * rv * 0.01
				tmpvFight += tfv
			} else {
				tmpvFight += float32(cfg.Power * val)
				zlog.Debugf("未找到指定值的偏移值, id:%v ", id)
			}
		}
	}

	for id, val := range pps {
		if cfg, ok := config_manager.GetConfigStcTableProperty_SheetProperty(int32(id)); ok {
			if rv, r1 := pvratio[id]; r1 {
				tfv := float32(cfg.Power1) * val * rv * 0.01
				tmppFight += tfv
			} else {
				tmppFight += float32(cfg.Power1) * val * 0.01
				zlog.Debugf("未找到指定值的偏移值, id:%v ", id)
			}
		}
	}

	h.Fight = int32(math.Round(float64(tmpvFight + tmppFight)))
}

// ------------------------------------分隔线----------------------------------------------------------------
// 获得升星需要的材料ItemId
type Cache_hero_info_upstar_items struct {
	Fragments *util.Set[int32] //碎片道具
	Items     *util.Set[int32] //材料道具
}

func (h *Cache_hero_info_field_hero) GetUpgradeStarConsumes() *Cache_hero_info_upstar_items {
	rst := &Cache_hero_info_upstar_items{
		Fragments: util.NewSet[int32](),
		Items:     util.NewSet[int32](),
	}
	if hero1, ok1 := config_manager.GetStcTableHero_SheetHeroConfig(h.CfgId); ok1 {
		if item2, ok2 := item.GetUpgradeHeroItems(constants.Item_Upgrade_HeroStar, hero1.Quality); ok2 {
			for id, _ := range item2 {
				if v3, ok3 := config_manager.GetTableItemSheetItemConfig(id); ok3 {
					rst.Fragments.Add(hero1.Unlockitemid)
					rst.Items.Add(v3.Id)
				}
			}
		}
	}
	return rst
}

// ------------------------------------分隔线----------------------------------------------------------------
// 获得升级需要的材料ItemId
type Cache_hero_info_uplv_items struct {
	Items *util.Set[int32] //材料道具
}

func (h *Cache_hero_info_field_hero) GetUpgradeLevelConsumes() *Cache_hero_info_uplv_items {
	rst := &Cache_hero_info_uplv_items{
		Items: util.NewSet[int32](),
	}
	if _, ok1 := config_manager.GetStcTableHero_SheetHeroConfig(h.CfgId); ok1 {
		if item2, ok2 := item.GetUpgradeHeroItems(constants.Item_Upgrade_HeroLv, -1); ok2 { //升级不做品质限制 hero1.Quality
			for id, _ := range item2 {
				if v3, ok3 := config_manager.GetTableItemSheetItemConfig(id); ok3 {
					rst.Items.Add(v3.Id)
				}
			}
		}
	}
	return rst
}

// ------------------------------------分隔线----------------------------------------------------------------
// 获得最大英雄升级等级
func (h *Cache_hero_info_field_hero) GetMax_UpLv(roleid int64) (int32, pb.ErrorCodeManager, bool) {
	if cfgStar, ok := config_manager.GetStcTableHero_SheetStarConfig(h.StarId); ok {
		maxLv := Hero_info_serviceObj.GetHeroMaxLevel()                 //等级表最高等级
		maxLv = int32(math.Min(float64(cfgStar.Level), float64(maxLv))) //星级限制的最高等级
		//根据建筑类型拿到所有相关建筑并与当前最大等级进行比对，找最小值
		if bvs, ok := build.GetRoleBuildsByType(roleid, constants.Build_Info_HeroCenter); ok {
			for bid, blvs := range bvs {
				for i := 0; i < len(blvs); i++ {
					cfg := config_manager.GetTableBuildSheetLevelConfig(bid, blvs[i])
					if cfg.Effect[0] > 0 { //等级上限
						maxLv = int32(math.Min(float64(cfg.Effect[0]), float64(maxLv))) //建筑等级限制的最高等级
					}
				}
			}
		}
		return maxLv, pb.ErrorCodeManager_SUCCESS, true
	} else {
		return 0, pb.ErrorCodeManager_HERO_INFO_NOT_HEROCFGID, false
	}
}

// 获得最大英雄升星等级
func (h *Cache_hero_info_field_hero) GetMax_UpStar(roleid int64) (int32, pb.ErrorCodeManager, bool) {
	if cfgStar, ok := config_manager.GetStcTableHero_SheetStarConfig(h.StarId); ok {
		maxLv := Hero_info_serviceObj.GetHeroMaxStar()                  //星级表最高等级
		maxLv = int32(math.Min(float64(cfgStar.Level), float64(maxLv))) //星级限制的最高等级
		//根据建筑类型拿到所有相关建筑并与当前最大等级进行比对，找最小值
		if bvs, ok := build.GetRoleBuildsByType(roleid, constants.Build_Info_HeroCenter); ok {
			for bid, blvs := range bvs {
				for i := 0; i < len(blvs); i++ {
					cfg := config_manager.GetTableBuildSheetLevelConfig(bid, blvs[i])
					if cfg.Effect[1] > 0 { //星级上限
						maxLv = int32(math.Min(float64(cfg.Effect[1]), float64(maxLv))) //建筑等级限制的最高等级
					}
				}
			}
		}
		return maxLv, pb.ErrorCodeManager_SUCCESS, true
	} else {
		return 0, pb.ErrorCodeManager_HERO_INFO_NOT_HEROCFGID, false
	}
}

// ===================================================================================================================
// 数据库表【hero_info】 skills字段
//
// Cache_hero_info_field_skill
//
// ===================================================================================================================
type Cache_hero_info_field_skill struct {
	Serid int32 //技能Serid
	CfgId int32 //技能配置Id
	Lv    int32 //技能等级
}

// ------------------------------------分隔线----------------------------------------------------------------
func (h *Cache_hero_info_field_skill) set_value_db(val string) {
	splitStr := strings.Split(val, "_")
	if len(splitStr) > 0 {
		for i, sv := range splitStr {
			if v, err := strconv.Atoi(sv); err == nil {
				switch i {
				case 0:
					{
						h.Serid = int32(v)
					}
				case 1:
					{
						h.CfgId = int32(v)
					}
				case 2:
					{
						h.Lv = int32(v)
					}
				}

			}

		}
	}
}

func (h *Cache_hero_info_field_skill) get_value_db() string {
	combinStr := strings.Join([]string{
		strconv.FormatInt(int64(h.Serid), 10),
		strconv.FormatInt(int64(h.CfgId), 10),
		strconv.FormatInt(int64(h.Lv), 10),
	}, "_")
	return combinStr
}

// ------------------------------------分隔线----------------------------------------------------------------

// ===================================================================================================================
// 数据库表【hero_info】 cells字段
//
// Cache_hero_info_field_cell
//
// ===================================================================================================================
type Cache_hero_info_field_cell struct {
	Serid int32 //细胞Serid
	CfgId int32 //细胞Id
	Lv    int32 //细胞等级
	Count int32 //细胞数量
	Idx   int32 //装备位置索引
}

// ------------------------------------分隔线----------------------------------------------------------------
func (h *Cache_hero_info_field_cell) set_value_db(val string) {
	splitStr := strings.Split(val, "_")
	if len(splitStr) > 0 {
		for i, sv := range splitStr {
			if v, err := strconv.Atoi(sv); err == nil {
				switch i {
				case 0:
					{
						h.Serid = int32(v)
					}
				case 1:
					{
						h.CfgId = int32(v)
					}
				case 2:
					{
						h.Lv = int32(v)
					}
				case 3:
					{
						h.Count = int32(v)
					}
				case 4:
					{
						h.Idx = int32(v)
					}
				}

			}

		}
	}
}

func (h *Cache_hero_info_field_cell) get_value_db() string {
	combinStr := strings.Join([]string{
		strconv.FormatInt(int64(h.Serid), 10),
		strconv.FormatInt(int64(h.CfgId), 10),
		strconv.FormatInt(int64(h.Lv), 10),
		strconv.FormatInt(int64(h.Count), 10),
		strconv.FormatInt(int64(h.Idx), 10),
	}, "_")
	return combinStr
}

// ------------------------------------分隔线----------------------------------------------------------------

// ------------------------------------分隔线----------------------------------------------------------------
func (h *Cache_hero_info_field_cell) To_PbData() *pb.HeroCellData {
	cell := &pb.HeroCellData{}
	cell.Serid = h.Serid
	cell.Cfgid = h.CfgId
	cell.Level = h.Lv
	cell.Count = h.Count
	cell.Idx = h.Idx
	return cell
}
